package com.yzcrm.erp.crm.service;


import java.math.BigDecimal;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.TxSerializable;
import com.yzcrm.common.config.exception.YzcrmException;
import com.yzcrm.common.config.paragetter.BasePageRequest;
import com.yzcrm.common.constant.BaseConstant;
import com.yzcrm.erp.admin.entity.AdminField;
import com.yzcrm.erp.admin.service.AdminExamineRecordService;
import com.yzcrm.erp.admin.service.AdminFieldService;
import com.yzcrm.erp.admin.service.AdminSceneService;
import com.yzcrm.erp.admin.service.AdminUserService;
import com.yzcrm.erp.crm.common.CrmEnum;
import com.yzcrm.erp.crm.service.CrmRecordService;
import com.yzcrm.erp.crm.common.QuotationCombEnum;
import com.yzcrm.erp.crm.entity.CrmQuotationCombination;
import com.yzcrm.erp.crm.entity.CrmQuotationMaterial;
import com.yzcrm.erp.crm.entity.CrmQuotationMaterialDetail;
import com.yzcrm.utils.AuthUtil;
import com.yzcrm.utils.BaseUtil;
import com.yzcrm.utils.ParamsUtil;
import com.yzcrm.utils.R;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;

import java.util.*;

import static com.yzcrm.common.packagemethod.packageMethods.*;
import static java.util.stream.Collectors.toList;


/**
 * Flowers bloom all over the ground, frequent urination urination not enough!
 * IDE: Created with by IntelliJ IDEA.
 * program: yzcrm
 *
 * @author :jones
 * github: https://github.com/luckyrxp
 * email: jonesxr@163.com
 * version: v 1.0
 *
 * <p>
 * <p>
 * date: 2020-08-22
 * time: 12:03
 * description:
 * Copyright(©) 2020 by Jones
 **/

public class CrmQuotationCombinationService {

    @Inject
    AdminSceneService adminSceneService;
    @Inject
    AdminExamineRecordService examineRecordService;
    @Inject
    CrmRecordService crmRecordService;
    @Inject
    AdminFieldService adminFieldService;


    public R filterConditionAndGetPageList(BasePageRequest<T> basePageRequest) {
        getEncapsulatingTheScene(basePageRequest);
        return getEnterLeaveStockPageList(basePageRequest);
    }

    /**
     * 查看报价列表页
     *
     * @param basePageRequest basePageRequest
     */
    public R getEnterLeaveStockPageList(BasePageRequest<T> basePageRequest) {

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Kv kv = new Kv();
        List<JSONObject> queryList = new ArrayList<>();
        Integer type = jsonObject.getInteger("type");

        //自定义字段列表
        Map<String, AdminField> fieldMap = adminSceneService.getAdminFieldMap(type);
        // 取得场景名称 同label
        String realm = CrmEnum.parse(type).getName();
        if (ObjectUtil.isNull(realm)) {
            return R.error("type不符合要求");
        }
        // 附加检索条件
        R theParameterContainsAnIllegalField1 = getR(basePageRequest, kv, queryList, type, fieldMap);
        if (theParameterContainsAnIllegalField1 != null) return theParameterContainsAnIllegalField1;
        // 获取排序字段
        R theParameterContainsAnIllegalField = getR(basePageRequest, kv, fieldMap);
        if (theParameterContainsAnIllegalField != null) return theParameterContainsAnIllegalField;
        // 开始生成条件SQL
        StringBuilder conditions = new StringBuilder();
        // 检索权限
        checkAuth(type, conditions);
        // 设置分页
        setPageMethod(basePageRequest, kv, queryList, conditions);
        // 拼接SQL
        SqlPara sqlPara = getSqlPara(kv, queryList, type, fieldMap, realm);
        // 检索数据
        List<Record> recordPage = Db.find(sqlPara);
        // 封装返回data
        JSONObject resultJsonObject = getJsonObject(kv, recordPage);
        return R.ok().put("data", resultJsonObject);
    }

    public JSONObject getJsonObject(Kv kv, List<Record> recordPage) {
        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", recordPage);

        SqlPara countSql = Db.getSqlPara("crm.quotationComb.queryQuotationCombListCount", kv);
        Integer count = Db.queryInt(countSql.getSql(), countSql.getPara());
        resultJsonObject.put("totalRow", count);
        return resultJsonObject;
    }

    public SqlPara getSqlPara(Kv kv, List<JSONObject> queryList, Integer type, Map<String, AdminField> fieldMap, String realm) {
        String selectSql = "select * ";
        List<String> batchList = adminSceneService.queryBatchId(queryList);
        if (batchList.size() == 0 && kv.containsKey("field")) {
            batchList.add("");
        }
        kv.set("select", selectSql).set("queryList", queryList).set("realm", realm).set("fieldMap", fieldMap).set("label", type);
        kv.set("batchList", batchList);
        SqlPara sqlPara;
        if (kv.getInt("fieldType") == 0) {
            sqlPara = Db.getSqlPara("crm.quotationComb.queryQuotationCombList2", kv);
        } else {
            sqlPara = Db.getSqlPara("crm.quotationComb.queryQuotationCombList1", kv);
        }
        return sqlPara;
    }

    public R getR(BasePageRequest<T> basePageRequest, Kv kv, List<JSONObject> queryList, Integer type, Map<String, AdminField> fieldMap) {
        JSONObject data = basePageRequest.getJsonObject().getJSONObject("data");
        if (!adminSceneService.appendSqlCondition(kv, fieldMap, queryList, data, type)) {
            return R.error("参数包含非法字段");
        }
        String search = basePageRequest.getJsonObject().getString("search");
        if (StrUtil.isNotEmpty(search)) {
            if (!adminSceneService.appendSqlSearch(type, queryList, search)) {
                return R.error("参数包含非法字段");
            }
            if (!kv.containsKey("fixed")) {
                kv.set("fixed", true);
            }
        }
        return null;
    }

    public R getR(BasePageRequest<T> basePageRequest, Kv kv, Map<String, AdminField> fieldMap) {
        String camelField = basePageRequest.getJsonObject().getString("sortField");
        String sortField = StrUtil.toUnderlineCase(camelField);
        String orderNum = basePageRequest.getJsonObject().getString("order");
        if (StrUtil.isEmpty(sortField) || StrUtil.isEmpty(orderNum)) {
            kv.set("orderByKey", "update_time").set("orderByType", "desc").set("fieldType", 1);
        } else {
            if (!ParamsUtil.isValid(sortField)) {
                return R.error("参数包含非法字段");
            }
            orderNum = "2".equals(orderNum) ? "asc" : "desc";
            kv.set("orderByKey", sortField).set("orderByType", orderNum).set("fieldType", fieldMap.get(sortField) != null ? fieldMap.get(sortField).getFieldType() : 0);
        }
        return null;
    }


    public void checkAuth(Integer type, StringBuilder conditions) {
        Long userId = BaseUtil.getUserId();
        List<Integer> roles = BaseUtil.getUser().getRoles();
        if (!BaseConstant.SUPER_ADMIN_USER_ID.equals(userId) && !roles.contains(BaseConstant.SUPER_ADMIN_ROLE_ID)) {
            String menuRealm = "";
            if (type == CrmEnum.CRM_QUOTATION_COMBINATION.getType()) {
                menuRealm = "index";
            }
            List<Long> longs = Aop.get(AdminUserService.class).queryUserByAuth(userId, menuRealm);
            if (longs != null && longs.size() > 0) {
                conditions.append(" and (views.owner_user_id in (").append(StrUtil.join(",", longs)).append(")");
                conditions.append(")");
            }
        }
    }


    /**
     * 检索部署方式返回添加产品选项
     *
     * @param basePageRequest basePageRequest
     * @return 部署方式
     */
    public R queryDeploy(BasePageRequest<T> basePageRequest) {
        int deploy = basePageRequest.getJsonObject().getInteger("deploy");
        Kv kv = Kv.create().set("deploy", deploy);
        List<Record> quotationList = Db.find(Db.getSqlPara("crm.quotationComb.queryDeployWayList", kv));
        return R.ok().put("data", quotationList);
    }

    /**
     * 检索创建人添加对应产品
     *
     * @param basePageRequest basePageRequest
     */
    public R queryProductList(BasePageRequest<T> basePageRequest) {
        String itemOption = basePageRequest.getJsonObject().getString(QuotationCombEnum.ITEM_OPTION.getName());
        String search = basePageRequest.getJsonObject().getString("search");
        Kv kv = Kv.create()
                .set(QuotationCombEnum.ITEM_OPTION.getName(), itemOption)
                .set("search", search)
                .set("page", (basePageRequest.getPage() - 1) * basePageRequest.getLimit())
                .set("limit", basePageRequest.getLimit());
        List<Record> productList = Db.find(Db.getSqlPara("crm.quotationComb.queryProductList", kv));
        List<Record> list = Db.find(Db.getSqlPara("crm.quotationComb.queryProductCount", kv));
        JSONObject result = new JSONObject();
        result.put("list", productList);
        result.put("totalRow", list.size());
        return R.ok().put("data", result);
    }


    /**
     * 新增或编辑
     *
     * @param jsonObject jsonObject
     * @return t or f
     */
    @Before(TxSerializable.class)
    public R saveOrUpdate(JSONObject jsonObject) {
        // 先保存 yzcrm_crm_quotation_combination
        CrmQuotationCombination combination = jsonObject.getObject("entity", CrmQuotationCombination.class);

        // 添加产品(物料)
        JSONArray jsonArrayMaterial = jsonObject.getJSONArray("quotationItems");

        List<Record> list = new LinkedList<>();
        boolean flag;
        // 如果 id为 0 则新增,反之修改
        if (combination.getQuotationId() == null) {
            // 主表报价列表保存
            int id = pageCombinationData(combination);
            // 创建审批流程
            Integer examineRecordId;
            Map<String, Integer> map = examineRecordService.saveExamineRecord(CrmEnum.CRM_QUOTATION_COMBINATION.getType(), BaseUtil.getUserId(),
                    Long.valueOf(combination.getOwnerUserId()), null, combination.getCheckStatus());
            if (map.get("status") == 0) {
                throw new YzcrmException("没有启动的审核步骤，不能添加！");
            } else {
                examineRecordId = map.get("id");
                combination.setExamineRecordId(examineRecordId);
            }
            if (combination.getCheckStatus() != null && combination.getCheckStatus() == QuotationCombEnum.SAVE_TO_DRAFT.getCode()) {
                combination.setCheckStatus(QuotationCombEnum.SAVE_TO_DRAFT.getCode());
            } else {
                combination.setCheckStatus(QuotationCombEnum.UNREVIEWED.getCode());
            }
            haveAuth(combination);
            /* 新增 */
            boolean save = Db.save("yzcrm_crm_quotation_combination", new Record().setColumns(combination));
            if (!save) {
                throw new YzcrmException("保存失败,请联系管理员!");
            }
            for (int i = 0; i < jsonArrayMaterial.size(); i++) {
                JSONArray valueList = jsonArrayMaterial.getJSONObject(i).getJSONArray("productList");
                String uuid = IdUtil.simpleUUID();
                saveFor(list, id, valueList, uuid, jsonArrayMaterial, i);
                saveIf(jsonArrayMaterial, id, i, uuid, valueList);
            }
            int[] ints = Db.batchSave("yzcrm_crm_quotation_material", list, list.size());
            if (ints.length < 1) {
                throw new YzcrmException("新增失败,请联系管理员!");
            }
            crmRecordService.addRecord(combination.getQuotationId(), CrmEnum.CRM_QUOTATION_COMBINATION);
        } else {
            /* 修改 */
            if (!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) &&
                    !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID) &&
                    Db.queryInt(Db.getSql("crm.quotationComb.queryIsRoUser"), BaseUtil.getUserId(), combination.getQuotationId()) > 0) {
                return R.error("没有权限");
            }

            Record combRecord = Db.findFirst(QuotationCombEnum.FIND_BY_ID.getName(), combination.getQuotationId());
            if (combRecord.getInt(QuotationCombEnum.RS.getName()) != QuotationCombEnum.WITHDRAWN.getCode()
                    && combRecord.getInt(QuotationCombEnum.RS.getName()) != QuotationCombEnum.REVIEW_REJECTED.getCode()
                    && combRecord.getInt(QuotationCombEnum.RS.getName()) != QuotationCombEnum.SAVE_TO_DRAFT.getCode()) {
                return R.error("不能编辑，请先撤回再编辑！");
            }

            Map<String, Integer> map = examineRecordService.saveExamineRecord(QuotationCombEnum.SAVE_TO_DRAFT.getCode(),
                    BaseUtil.getUserId(), Long.valueOf(combRecord.getInt(QuotationCombEnum.OUI.getName())),
                    combRecord.getInt(QuotationCombEnum.ERI.getName()), combination.getCheckStatus());
            if (map.get(QuotationCombEnum.STATUS.getName()) == 0) {
                return R.error("没有启动的审核步骤，不能添加！");
            } else {
                combination.setExamineRecordId(map.get("id"));
            }
            if (combination.getCheckStatus() != null && combination.getCheckStatus() == QuotationCombEnum.SAVE_TO_DRAFT.getCode()) {
                combination.setCheckStatus(QuotationCombEnum.SAVE_TO_DRAFT.getCode());
            } else {
                combination.setCheckStatus(QuotationCombEnum.UNREVIEWED.getCode());
            }
            combination.setQuotationItemId(combination.getInt("quotation_item_id"));
            combination.setUpdateTime(DateUtil.date());
            combination.setUpdateUserId(BaseUtil.getUserId().intValue());
            if (!combination.update()) {
                // 更新
                throw new YzcrmException("编辑失败,请联系管理员!");
            }

            Integer quotationId = combination.getInt("quotation_id");
            Kv kv = Kv.create().set("quotationId", quotationId);
            int id = combination.getInt("quotation_id");

            if (combRecord.getInt(QuotationCombEnum.RS.getName()) == QuotationCombEnum.EXAMINATION_PASSED.getCode() ||
                    combRecord.getInt(QuotationCombEnum.RS.getName()) == QuotationCombEnum.UNDER_REVIEW.getCode()) {
                return R.error("报价项目正在审核中或已审核通过，不能更改部署方式");
            } else if (!combination.getQuotationItemId().equals(combination.getInt("quotation_item_id")) || jsonArrayMaterial.size() == 0) {
                Db.update(Db.getSqlPara("crm.quotationComb.updateMaterialList", kv));
                Db.update(Db.getSqlPara("crm.quotationComb.updateMaterialDetail", kv));
            }
            for (int i = 0; i < jsonArrayMaterial.size(); i++) {
                JSONArray valueList = jsonArrayMaterial.getJSONObject(i).getJSONArray("productList");
                String uuid1 = IdUtil.simpleUUID();
                updateFor(list, valueList, id, i, jsonArrayMaterial, uuid1, combination);
                updateIf(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
        flag = true;
        return flag ? R.ok() : R.error("操作失败,请联系管理员!");
    }

    /**
     * 封装数据
     *
     * @param combination combination
     * @return id
     */
    private int pageCombinationData(CrmQuotationCombination combination) {
        combination.setBatchId(IdUtil.simpleUUID());
        combination.setCreateTime(DateUtil.date());
        combination.setCreateUserId(BaseUtil.getUserId().intValue());
        combination.setOwnerUserId(BaseUtil.getUserId().intValue());
        combination.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
        combination.setRoUserId(QuotationCombEnum.COMMA.getName());
        combination.setRwUserId(QuotationCombEnum.COMMA.getName());
        combination.setUpdateTime(DateUtil.date());
        combination.setUpdateUserId(BaseUtil.getUserId().intValue());
        Record first = Db.findFirst("SELECT MAX(quotation_id) 'id' FROM `yzcrm_crm_quotation_combination`");
        int id;
        if (first.getStr("id") == null) {
            id = 1;
        } else {
            id = first.getInt("id") + 1;
        }
        combination.setQuotationId(id);
        return id;
    }


    private void updateIf(JSONArray jsonArrayMaterial, int i, JSONArray valueList, CrmQuotationCombination combination, String uuid1) {
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
            if (valueList.size() > 0) {
                updateMaterialDetail(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
            if (valueList.size() > 0) {
                updateMaterialDetail(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
            if (valueList.size() > 0) {
                updateMaterialDetail(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
            if (valueList.size() > 0) {
                updateMaterialDetail(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
            if (valueList.size() > 0) {
                updateMaterialDetail(jsonArrayMaterial, i, valueList, combination, uuid1);
            }
        }
    }

    private void updateFor(List<Record> list, JSONArray valueList, int id, int i, JSONArray jsonArrayMaterial, String uuid1, CrmQuotationCombination combination) {
        boolean b;
        Record record;
        List<Integer> addList = new LinkedList<>();
        String batchMaterialId = null;
        Integer quotationId = null;
        // 判断物料是否被清空 通过 quotation_id 和 batch_material_id 分组进行查询状态为 1的数据
        List<Record> listMaterial = Db.find("SELECT quotation_id,batch_material_id FROM yzcrm_crm_quotation_material WHERE del_flog = 1 AND quotation_id = ? GROUP BY material_option", combination.getQuotationId());
        if (jsonArrayMaterial.size() != listMaterial.size()) {
            listMaterial.forEach(material -> {
                Db.update("UPDATE yzcrm_crm_quotation_material SET del_flog = 2 WHERE batch_material_id = ?", material.getStr("batch_material_id"));
            });
        } else {
            for (int n = 0; n < valueList.size(); n++) {
                Integer productMaterialId = valueList.getJSONObject(n).getInteger("productMaterialId");
                addList.add(productMaterialId);
                batchMaterialId = valueList.getJSONObject(n).getString("batchMaterialId");
                quotationId = valueList.getJSONObject(n).getInteger("quotationId");
            }
            // 同 quotation_id 和 batch_material_id 查询 yzcrm_crm_quotation_material 的 id
            List<Integer> integerList = new LinkedList<>();
            List<Record> records = Db.find("select product_material_id from yzcrm_crm_quotation_material where quotation_id = ? and batch_material_id = ?", quotationId, batchMaterialId);
            records.forEach(r -> {
                Integer productMaterialId1 = r.getInt("product_material_id");
                integerList.add(productMaterialId1);
            });
            List<Integer> diffId = integerList.stream().filter(item -> !addList.contains(item)).collect(toList());
            for (Integer integer : diffId) {
                Db.update("update yzcrm_crm_quotation_material set del_flog = 2 where product_material_id = ?", integer);
            }
        }
        for (int j = 0; j < valueList.size(); j++) {
            JSONObject jsonObjectMaterial = valueList.getJSONObject(j);
            CrmQuotationMaterial material = jsonObjectMaterial.toJavaObject(CrmQuotationMaterial.class);
            Integer productMaterialId = valueList.getJSONObject(j).getInteger("productMaterialId");
            material.setUpdateTime(DateUtil.date());
            material.setUpdateUserId(BaseUtil.getUserId().intValue());
            material.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
            if (productMaterialId == null) {
                material.setQuotationId(id);
                if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
                    material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_HARDWARE.getCode());
                    material.setBatchMaterialId(uuid1);
                }
                if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
                    material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_AUTH.getCode());
                    material.setBatchMaterialId(uuid1);
                }
                if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
                    material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getCode());
                    material.setBatchMaterialId(uuid1);
                }
                if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
                    material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getCode());
                    material.setBatchMaterialId(uuid1);
                }
                if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
                    material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getCode());
                    material.setBatchMaterialId(uuid1);
                }
                material.setCreateUserId(BaseUtil.getUserId().intValue());
                material.setCreateTime(DateUtil.date());
                material.setProductRate(jsonArrayMaterial.getJSONObject(i).getInteger("rate"));
                record = new Record().setColumns(material);
                b = Db.save("yzcrm_crm_quotation_material", record);
            } else {
                material.setProductMaterialId(productMaterialId);
                material.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
                record = new Record().setColumns(material);
                b = Db.update("yzcrm_crm_quotation_material", "product_material_id", record);
            }
            if (!b) {
                throw new YzcrmException("编辑失败,请联系管理员!");
            }
        }
    }

    private void saveIf(JSONArray jsonArrayMaterial, int id, int i, String uuid, JSONArray valueList) {
        if (valueList.size() > 0) {
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
                saveMaterialDetail(jsonArrayMaterial, id, i, uuid);
            }
        }
        if (valueList.size() > 0) {
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
                saveMaterialDetail(jsonArrayMaterial, id, i, uuid);
            }
        }
        if (valueList.size() > 0) {
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
                saveMaterialDetail(jsonArrayMaterial, id, i, uuid);
            }
        }
        if (valueList.size() > 0) {
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
                saveMaterialDetail(jsonArrayMaterial, id, i, uuid);
            }
        }
        if (valueList.size() > 0) {
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
                saveMaterialDetail(jsonArrayMaterial, id, i, uuid);
            }
        }
    }

    private void saveFor(List<Record> list, int id, JSONArray valueList, String uuid, JSONArray jsonArray, int i) {
        Record record;
        for (int j = 0; j < valueList.size(); j++) {
            JSONObject jsonObjectMaterial = valueList.getJSONObject(j);
            CrmQuotationMaterial material = jsonObjectMaterial.toJavaObject(CrmQuotationMaterial.class);
            material.setQuotationId(id);
            if (jsonArray.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
                material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_HARDWARE.getCode());
            }
            if (jsonArray.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
                material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_AUTH.getCode());
            }
            if (jsonArray.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
                material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getCode());
            }
            if (jsonArray.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
                material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getCode());
            }
            if (jsonArray.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
                material.setMaterialOption(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getCode());
            }
            material.setProductRate(jsonArray.getJSONObject(0).getInteger("rate"));
            material.setCreateTime(DateUtil.date());
            material.setCreateUserId(BaseUtil.getUserId().intValue());
            material.setUpdateTime(DateUtil.date());
            material.setUpdateUserId(BaseUtil.getUserId().intValue());
            material.setRemark(material.getRemark());
            material.setBatchMaterialId(uuid);
            material.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
            record = new Record().setColumns(material);
            list.add(record);
        }
    }

    private void updateMaterialDetail(JSONArray jsonArrayMaterial, int i, JSONArray valueList, CrmQuotationCombination combination, String uuid1) {
        boolean b;
        String batchMaterialId = null;
        for (int j = 0; j < valueList.size(); j++) {
            batchMaterialId = valueList.getJSONObject(j).getString("batchMaterialId");
        }
        CrmQuotationMaterialDetail crmMaterialDetail = new CrmQuotationMaterialDetail();
        //小计可能会改变
        crmMaterialDetail.setSubtotal(new BigDecimal(jsonArrayMaterial.getJSONObject(i).getString("subtotal")));
        crmMaterialDetail.setVatRate(jsonArrayMaterial.getJSONObject(i).getInteger("rate"));
        crmMaterialDetail.setUpdateUserId(BaseUtil.getUserId().intValue());
        crmMaterialDetail.setUpdateTime(DateUtil.date());
        crmMaterialDetail.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
        Record recordMaterialDetail;
        if (batchMaterialId == null) {
            crmMaterialDetail.setCreateTime(DateUtil.date());
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
                crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_HARDWARE.getCode());
                crmMaterialDetail.setBatchMaterialId(uuid1);
            }
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
                crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_AUTH.getCode());
                crmMaterialDetail.setBatchMaterialId(uuid1);
            }
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
                crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getCode());
                crmMaterialDetail.setBatchMaterialId(uuid1);
            }
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
                crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getCode());
                crmMaterialDetail.setBatchMaterialId(uuid1);
            }
            if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
                crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getCode());
                crmMaterialDetail.setBatchMaterialId(uuid1);
            }
            crmMaterialDetail.setQuotationId(combination.getQuotationId());
            crmMaterialDetail.setCreateUserId(BaseUtil.getUserId().intValue());
            recordMaterialDetail = new Record().setColumns(crmMaterialDetail);
            b = Db.save("yzcrm_crm_quotation_material_detail", recordMaterialDetail);
        } else {
            Record materialDetailId = Db.findFirst("SELECT material_detail_id FROM yzcrm_crm_quotation_material_detail WHERE del_flog = 1 AND batch_material_id = ?", batchMaterialId);
            crmMaterialDetail.setMaterialDetailId(materialDetailId.getInt("material_detail_id"));
            recordMaterialDetail = new Record().setColumns(crmMaterialDetail);
            b = Db.update("yzcrm_crm_quotation_material_detail", "material_detail_id", recordMaterialDetail);
        }
        if (!b) {
            throw new YzcrmException("编辑失败,请联系管理员!");
        }
    }

    private void saveMaterialDetail(JSONArray jsonArrayMaterial, int id, int i, String uuid) {
        CrmQuotationMaterialDetail crmMaterialDetail = new CrmQuotationMaterialDetail();
        crmMaterialDetail.setQuotationId(id);
        crmMaterialDetail.setBatchMaterialId(uuid);
        crmMaterialDetail.setSubtotal(new BigDecimal(jsonArrayMaterial.getJSONObject(i).getString("subtotal")));
        crmMaterialDetail.setVatRate(jsonArrayMaterial.getJSONObject(i).getInteger("rate"));
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_HARDWARE.getName())) {
            crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_HARDWARE.getCode());
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_AUTH.getName())) {
            crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_AUTH.getCode());
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getName())) {
            crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_LOCAL_DEPLOY_AUTH.getCode());
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getName())) {
            crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_ANNUAL_FEE.getCode());
        }
        if (jsonArrayMaterial.getJSONObject(i).getString(QuotationCombEnum.ITEM_OPTION.getName()).equals(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getName())) {
            crmMaterialDetail.setItemOption(QuotationCombEnum.ITEM_OPTION_ARTIFICIAL.getCode());
        }
        crmMaterialDetail.setCreateUserId(BaseUtil.getUserId().intValue());
        crmMaterialDetail.setUpdateUserId(BaseUtil.getUserId().intValue());
        crmMaterialDetail.setCreateTime(DateUtil.date());
        crmMaterialDetail.setUpdateTime(DateUtil.date());
        crmMaterialDetail.setDelFlog(QuotationCombEnum.AVAILABLE.getCode());
        Record recordMaterialDetail = new Record().setColumns(crmMaterialDetail);
        if (!Db.save("yzcrm_crm_quotation_material_detail", recordMaterialDetail)) {
            throw new YzcrmException("新增失败,请联系管理员!");
        }
    }


    public void haveAuth(CrmQuotationCombination combination) {

        if (combination.getInt("review_price") == QuotationCombEnum.MORE_THAN_PRICE_VAT_RATE.getCode()) {
            // 如果销售价格低总监价格
            combination.setReviewPrice(QuotationCombEnum.MORE_THAN_PRICE_VAT_RATE.getCode());
        } else {
            combination.setReviewPrice(QuotationCombEnum.LESS_THAN_PRICE_VAT_RATE.getCode());
        }
        if (combination.getInt("review_rate") == QuotationCombEnum.MORE_THAN_PRICE_VAT_RATE.getCode()) {
            // 税率低于 13%时
            combination.setReviewRate(QuotationCombEnum.MORE_THAN_PRICE_VAT_RATE.getCode());
        } else {
            combination.setReviewRate(QuotationCombEnum.LESS_THAN_PRICE_VAT_RATE.getCode());
        }

    }

    /**
     * 检索报价详情
     *
     * @param basePageRequest basePageRequest
     */
    public R queryDetails(BasePageRequest<T> basePageRequest) {
        Integer quotationId = basePageRequest.getJsonObject().getInteger("quotationId");
        /* 检索数据 分两次进行查询 第一次进行 yzcrm_crm_quotation_combination 主表和 yzcrm_crm_quotation_item 从表关联检索 */
        Record quotationCombItem = Db.findFirst(Db.getSqlPara("crm.quotationComb.queryQuotationCombLeftJoinItem",
                Kv.by("quotationId", quotationId)));
        // 第二次根据 quotationId 进行单表进行检索
        List<Record> listRecord = Db.find(Db.getSqlPara("crm.quotationComb.queryQuotationCombMaterial",
                Kv.by("quotationId", quotationId)));

        LinkedList<Record> list = new LinkedList<>();
        getMaterialOptionType(list, quotationCombItem, listRecord);
        Record resultZ;
        /* 当前用户是否有权限查看总监价格 1 有 2 无 */
        if (!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) &&
                !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID) &&
                Db.queryInt(Db.getSql("crm.quotationComb.queryIsRoUser"), BaseUtil.getUserId(), quotationId) > 0) {
            resultZ = quotationCombItem.set("isCheck", QuotationCombEnum.NO.getCode());
        } else {
            resultZ = quotationCombItem.set("isCheck", QuotationCombEnum.HAVE.getCode());
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("baseInfo", resultZ);
        jsonObject.put("listData", list);
        return R.ok().put("data", jsonObject);
    }


    @Before(TxSerializable.class)
    public R delQuotationByIds(String quotationByIds) {
        List<String> ids = StrUtil.splitTrim(quotationByIds, ",");
        List<String> listIds = new LinkedList<>(ids);
        List<String> quotationIds = new LinkedList<>();
        if (listIds.size() < 1) {
            return R.error("选择不能为空,请选中你要删除的数据!");
        }
        String permissions = "crm:quotation:delete";
        if (!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) && !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID)
                && !AuthUtil.isHavaAuth(permissions)
                && Db.queryInt(Db.getSql("crm.quotation.queryIsOwnerUser"), BaseUtil.getUserId(), listIds) <= 0) {
            return R.error("没有权限");
        }
        Kv kv = Kv.create().set("listIds", listIds);
        // 过滤掉审核通过和审核中的数据
        List<Record> list = Db.find(Db.getSqlPara("crm.quotationComb.findQuotationIds", kv));
        list.forEach(record -> {
            quotationIds.add(String.valueOf(record.getInt("quotation_id")));
        });
        Kv k = Kv.create().set("listIds", quotationIds);
        int updateQuComb = Db.update(Db.getSqlPara("crm.quotationComb.updateQuotationIds", k));
        if (updateQuComb < 1) {
            throw new YzcrmException("删除数据失败,请联系管理员!");
        }
        // 更新物料表的状态
        int updateMaterial = Db.update(Db.getSqlPara("crm.quotationComb.updateMaterialIds", k));
        int updateMaterialDetail = Db.update(Db.getSqlPara("crm.quotationComb.updateMaterialDetailIds", k));
        if (updateMaterial < 1 || updateMaterialDetail < 1) {
            throw new YzcrmException("删除数据失败,请联系管理员!");
        }
        return R.ok();
    }

    public List<Record> queryField(Integer id) {
        Record record = queryById(id);
        return adminFieldService.queryUpdateField(CrmEnum.CRM_QUOTATION_COMBINATION.getType(), record);
    }

    public Record queryById(Integer id) {
        Record record = Db.findFirst(Db.getSql("crm.quotationComb.queryById"), id);
        List<Record> recordList = Db.find("select name,value from `yzcrm_admin_fieldv` where batch_id = ?", record.getStr("batch_id"));
        recordList.forEach(field -> record.set(field.getStr("name"), field.getStr("value")));
        return record;
    }

    public R queryMaterialList(int quotationId) {

        if (!StrUtil.isNotBlank(String.valueOf(quotationId))) {
            return R.error("没有查询到数据,请联系管理员!");
        }
        Record record = Db.findFirst(Db.getSqlPara("crm.quotationComb.queryQuotationCombLeftJoinItem",
                Kv.by("quotationId", quotationId)));
        List<Record> listRecord = Db.find(Db.getSqlPara("crm.quotationComb.queryQuotationCombMaterial",
                Kv.by("quotationId", quotationId)));
        if (CollectionUtils.isEmpty(listRecord)) {
            return R.error("没有查询到数据,请联系管理员!");
        }
        LinkedList<Record> resultList = new LinkedList<>();
        getMaterialOptionType(resultList, record, listRecord);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("listData", resultList);
        return R.ok().put("data", jsonObject);
    }

    public R queryByBusinessIdForQuotationList(int businessId, boolean isValid, String search) {

        List<Record> list = Db.find(Db.getSqlPara("crm.quotationComb.queryByBusinessIdForQuotationList",
                Kv.create().set("businessId", businessId).set("search", search).set("checkStatus", isValid)));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", list);
        return R.ok().put("data", jsonObject);
    }
}
